﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using M3G;
using System.Drawing;


namespace MyTestProject {

    public class TestImageCube {

        /**
         * コンストラクターのテスト1
         * 白紙の画像
         * */
        [Fact]
        public void TestConstructor1 () {
            var img = new ImageCube (ImageCube.RGB, 64);

            Assert.Equal (ImageCube.RGB, img.Format);
            Assert.Equal (64, img.Width);
            Assert.Equal (64, img.Height);
            Assert.Equal (true, img.Mutable);
            Assert.Equal (true, img.MipmapGenerateEnabled);
            Assert.Equal (true, img.Mipmapped);

            img.SaveMipmapPyramid (ImageCube.PosX, "TestImageCube-Constructor1-PosX.png");
            img.SaveMipmapPyramid (ImageCube.NegX, "TestImageCube-Constructor1-NegX.png");
            img.SaveMipmapPyramid (ImageCube.PosY, "TestImageCube-Constructor1-PosY.png");
            img.SaveMipmapPyramid (ImageCube.NegY, "TestImageCube-Constructor1-NegY.png");
            img.SaveMipmapPyramid (ImageCube.PosZ, "TestImageCube-Constructor1-PosZ.png");
            img.SaveMipmapPyramid (ImageCube.NegZ, "TestImageCube-Constructor1-NegZ.png");
        }

        /**
         * コンストラクターのテスト2
         * ミップマップ階層の完全指定
         * */
        [Fact]
        public void TestConstructor2 () {
            var pixels = new byte[6][][];
            for (var f=0; f < 6; f++) {
                pixels[f] = new byte[9][];
                for (var m=0; m < 9; m++) {
                    int miplevelWidth = (int)Math.Ceiling (256 / Math.Pow (2, m));
                    int miplevelHeight = (int)Math.Ceiling (256 / Math.Pow (2, m));
                    pixels[f][m] = new byte[miplevelWidth * miplevelHeight * 3];
                    for (var i=0; i < pixels[f][m].Length; i++) {
                        pixels[f][m][i] = 255;
                    }
                }
            }
            var img = new ImageCube (ImageCube.RGB, 256, pixels);

            img.SaveMipmapPyramid (ImageCube.PosX, "TestImageCube-Constructor2-PosX.png");
            img.SaveMipmapPyramid (ImageCube.NegX, "TestImageCube-Constructor2-NegX.png");
            img.SaveMipmapPyramid (ImageCube.PosY, "TestImageCube-Constructor2-PosY.png");
            img.SaveMipmapPyramid (ImageCube.NegY, "TestImageCube-Constructor2-NegY.png");
            img.SaveMipmapPyramid (ImageCube.PosZ, "TestImageCube-Constructor2-PosZ.png");
            img.SaveMipmapPyramid (ImageCube.NegZ, "TestImageCube-Constructor2-NegZ.png");
        }

        /**
         * コンストラクターのテスト3
         * 6つのBitmapオブジェクトを使ったキューブマップの作成
         * */
        [Fact]
        public void TestConstructor3 () {
            var bitmaps = new Bitmap[6];
            bitmaps[0] = new Bitmap ("Girl-3.png");
            bitmaps[1] = new Bitmap ("Girl-12.png");
            bitmaps[2] = new Bitmap ("Girl-18.png");
            bitmaps[3] = new Bitmap ("Girl-20.png");
            bitmaps[4] = new Bitmap ("Girl-25.png");
            bitmaps[5] = new Bitmap ("Girl-30.png");

            var img = new ImageCube (ImageCube.RGB, bitmaps);

            img.SaveMipmapPyramid (ImageCube.PosX, "TestImageCube-Constructor3-PosX.png");
            img.SaveMipmapPyramid (ImageCube.NegX, "TestImageCube-Constructor3-NegX.png");
            img.SaveMipmapPyramid (ImageCube.PosY, "TestImageCube-Constructor3-PosY.png");
            img.SaveMipmapPyramid (ImageCube.NegY, "TestImageCube-Constructor3-NegY.png");
            img.SaveMipmapPyramid (ImageCube.PosZ, "TestImageCube-Constructor3-PosZ.png");
            img.SaveMipmapPyramid (ImageCube.NegZ, "TestImageCube-Constructor3-NegZ.png");
        }

        /**
         * 画像の書き換えのテスト1
         * byte[]で指定
         * */
        [Fact]
        public void TestSet1 () {
            var img = new ImageCube (ImageCube.RGB, 256);

            img.Set (ImageCube.PosX, 0, 0, 0, 256, 256, ImageCube.ConvertToPixels (ImageCube.RGB, new Bitmap ("Girl-3.png")));
            img.Set (ImageCube.NegX, 0, 0, 0, 256, 256, ImageCube.ConvertToPixels (ImageCube.RGB, new Bitmap ("Girl-12.png")));
            img.Set (ImageCube.PosY, 0, 0, 0, 256, 256, ImageCube.ConvertToPixels (ImageCube.RGB, new Bitmap ("Girl-18.png")));
            img.Set (ImageCube.NegY, 0, 0, 0, 256, 256, ImageCube.ConvertToPixels (ImageCube.RGB, new Bitmap ("Girl-20.png")));
            img.Set (ImageCube.PosZ, 0, 0, 0, 256, 256, ImageCube.ConvertToPixels (ImageCube.RGB, new Bitmap ("Girl-25.png")));
            img.Set (ImageCube.NegZ, 0, 0, 0, 256, 256, ImageCube.ConvertToPixels (ImageCube.RGB, new Bitmap ("Girl-30.png")));

            img.SaveMipmapPyramid (ImageCube.PosX, "TestImageCube-Set1-PosX.png");
            img.SaveMipmapPyramid (ImageCube.NegX, "TestImageCube-Set1-NegX.png");
            img.SaveMipmapPyramid (ImageCube.PosY, "TestImageCube-Set1-PosY.png");
            img.SaveMipmapPyramid (ImageCube.NegY, "TestImageCube-Set1-NegY.png");
            img.SaveMipmapPyramid (ImageCube.PosZ, "TestImageCube-Set1-PosZ.png");
            img.SaveMipmapPyramid (ImageCube.NegZ, "TestImageCube-Set1-NegZ.png");
        }

       /**
        * 画像の書き換えのテスト2
        * uint[]で指定
        * */
        [Fact]
        public void TestSet2 () {
            var img = new ImageCube (ImageCube.RGB, 256);

            var bitmap     = new Bitmap ("Girl-18.png");
            var uintPixels = new uint[bitmap.Width * bitmap.Height];
            for (var y=0; y < bitmap.Height; y++) {
                for (var x=0; x < bitmap.Width; x++) {
                    var c = bitmap.GetPixel (x, y);
                    uintPixels[(y * bitmap.Width + x)] = (uint)(c.A << 24 | c.R << 16 | c.G << 8 | c.B << 0);
                }
            }

            img.Set (ImageCube.PosX, 0, 0, 0, 256, 256, uintPixels);
            img.Set (ImageCube.NegX, 0, 0, 0, 256, 256, uintPixels);
            img.Set (ImageCube.PosY, 0, 0, 0, 256, 256, uintPixels);
            img.Set (ImageCube.NegY, 0, 0, 0, 256, 256, uintPixels);
            img.Set (ImageCube.PosZ, 0, 0, 0, 256, 256, uintPixels);
            img.Set (ImageCube.NegZ, 0, 0, 0, 256, 256, uintPixels);

            img.SaveMipmapPyramid (ImageCube.PosX, "TestImageCube-Set2-PosX.png");
            img.SaveMipmapPyramid (ImageCube.NegX, "TestImageCube-Set2-NegX.png");
            img.SaveMipmapPyramid (ImageCube.PosY, "TestImageCube-Set2-PosY.png");
            img.SaveMipmapPyramid (ImageCube.NegY, "TestImageCube-Set2-NegY.png");
            img.SaveMipmapPyramid (ImageCube.PosZ, "TestImageCube-Set2-PosZ.png");
            img.SaveMipmapPyramid (ImageCube.NegZ, "TestImageCube-Set2-NegZ.png");
        }

        /**
         * 画像の書き換えのテスト3
         * ushort[]で指定
         * */
        [Fact]
        public void TestSet3 () {
            var img = new ImageCube (ImageCube.RGB, 256);

            var bitmap       = new Bitmap ("Girl-20.png");
            var ushortPixels = new ushort[bitmap.Width * bitmap.Height];
            for (var y=0; y < bitmap.Height; y++) {
                for (var x=0; x < bitmap.Width; x++) {
                    var r = (int)(bitmap.GetPixel (x, y).R / 255.0f * 31.0f);
                    var g = (int)(bitmap.GetPixel (x, y).G / 255.0f * 63.0f);
                    var b = (int)(bitmap.GetPixel (x, y).B / 255.0f * 31.0f);
                    ushortPixels[y * bitmap.Width + x] = (ushort)(r << 11 | g << 5 | b << 0);
                }
            }

            img.Set (ImageCube.PosX, 0, 0, 0, 256, 256, ushortPixels);
            img.Set (ImageCube.NegX, 0, 0, 0, 256, 256, ushortPixels);
            img.Set (ImageCube.PosY, 0, 0, 0, 256, 256, ushortPixels);
            img.Set (ImageCube.NegY, 0, 0, 0, 256, 256, ushortPixels);
            img.Set (ImageCube.PosZ, 0, 0, 0, 256, 256, ushortPixels);
            img.Set (ImageCube.NegZ, 0, 0, 0, 256, 256, ushortPixels);

            img.SaveMipmapPyramid (ImageCube.PosX, "TestImageCube-Set3-PosX.png");
            img.SaveMipmapPyramid (ImageCube.NegX, "TestImageCube-Set3-NegX.png");
            img.SaveMipmapPyramid (ImageCube.PosY, "TestImageCube-Set3-PosY.png");
            img.SaveMipmapPyramid (ImageCube.NegY, "TestImageCube-Set3-NegY.png");
            img.SaveMipmapPyramid (ImageCube.PosZ, "TestImageCube-Set3-PosZ.png");
            img.SaveMipmapPyramid (ImageCube.NegZ, "TestImageCube-Set3-NegZ.png");
        }

       /**
        * 画像の書き換えのテスト3
        * Bitmapで指定
        * */
        [Fact]
        public void TestSet4 () {
            var img    = new ImageCube (ImageCube.RGB, 256);
            var bitmap = new Bitmap ("Girl-25.png");

            img.Set (ImageCube.PosX, 0, 0, 0, 0, 0, 256, 256, bitmap);
            img.Set (ImageCube.NegX, 0, 0, 0, 0, 0, 256, 256, bitmap);
            img.Set (ImageCube.PosY, 0, 0, 0, 0, 0, 256, 256, bitmap);
            img.Set (ImageCube.NegY, 0, 0, 0, 0, 0, 256, 256, bitmap);
            img.Set (ImageCube.PosZ, 0, 0, 0, 0, 0, 256, 256, bitmap);
            img.Set (ImageCube.NegZ, 0, 0, 0, 0, 0, 256, 256, bitmap);

            img.SaveMipmapPyramid (ImageCube.PosX, "TestImageCube-Set3-PosX.png");
            img.SaveMipmapPyramid (ImageCube.NegX, "TestImageCube-Set3-NegX.png");
            img.SaveMipmapPyramid (ImageCube.PosY, "TestImageCube-Set3-PosY.png");
            img.SaveMipmapPyramid (ImageCube.NegY, "TestImageCube-Set3-NegY.png");
            img.SaveMipmapPyramid (ImageCube.PosZ, "TestImageCube-Set3-PosZ.png");
            img.SaveMipmapPyramid (ImageCube.NegZ, "TestImageCube-Set3-NegZ.png");
        }

        [Fact]
        public void TestDuplicate () {
            // 未実装
        }
    }
}
